/*
 * @(#)DrawGraph.java   09/10/11
 * 
 * Copyright (C) 2009 Ecole des Mines d'Ales
 *
 * This library itfP free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library itfP distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Contact: yulinz88@gmail.com
 */



package fr.ema.arch3d.editor.mainGUI;

import fr.ema.arch3d.editor.Evolution;
import fr.ema.arch3d.editor.ass.AssADLText;
import fr.ema.arch3d.editor.ass.DrawAssImpl;
import fr.ema.arch3d.editor.config.ConfigADLText;
import fr.ema.arch3d.editor.config.DrawConfigImpl;
import fr.ema.arch3d.editor.mainGUI.BNFText.BNFText;
import fr.ema.arch3d.editor.mainGUI.TreeTable.ADLElementModel;
import fr.ema.arch3d.editor.mainGUI.TreeTable.JTreeTable;
import fr.ema.arch3d.editor.mainGUI.archExplorer.ArchTree;
import fr.ema.arch3d.editor.mainGUI.fileDirectory.FileTree;
import fr.ema.arch3d.editor.mainGUI.listeners.ArchTreeSelectionListener;
import fr.ema.arch3d.editor.mainGUI.listeners.SyncGraphSelectionListener;
import fr.ema.arch3d.editor.spec.SpecADLText;
import fr.ema.arch3d.editor.spec.DrawSpecImpl;
import fr.ema.arch3d.jmodel.configuration.Configuration;
import fr.ema.arch3d.jmodel.specification.DefaultSpecification;
import fr.ema.arch3d.jmodel.specification.Specification;
import fr.ema.arch3d.ref.Fractal;


import org.jgraph.JGraph;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;

import java.io.PipedInputStream;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

//~--- classes ----------------------------------------------------------------

/**
 * Class description
 *
 *
 * @version        1.0, 09/09/13
 * @author         Huaxi (Yulin) ZHANG
 */
public class DrawGraph {

    /** Field description */
    static private final String newline = "\n";

    /** Field description */
    public static ArchTree archTree;

    /** Field description */
    public static FileTree fileTree;

    /** Field description */
    public static JGraph graphA;

    /** Field description */
    public static JGraph graphC;

    /** Field description */
    public static JGraph graphS;

    /** Field description */
    public static JScrollPane treeTablePane, graphPane;

    /** the textPane to show the ADL description */
    public static JTextPane adlTextPane;
    
    /** Field description */
    private static JTreeTable specTreeTable, configTreeTable, assTreeTable;

    /** Field description */
    private final PipedInputStream pin = new PipedInputStream();

    /** Field description */
    private final PipedInputStream pin2 = new PipedInputStream();

    /** Field description */
    private Component ass;

    /** Field description */
    JButton button;

    /** Field description */
    private Configuration config;

    /** Field description */
    private JSplitPane consolePane;

    /** Field description */
    private JTextArea consoleTextArea;

    /** Field description */
    JFileChooser fc;

    /** Field description */
    private JComponent fileTreePanel, archTreePanel;

    /** Field description */
    private JFrame frame;

    /** Field description */
    private boolean quit;

    /** Field description */
    private Thread reader;

    /** Field description */
    private Thread reader2;

    /** Field description */
    private Specification spec;

    /** Field description */
    private JTabbedPane viewTabbedPane, editorTabbedPane, propertyTabbedPane;

    /** Field description */
    private JEditorPane xmlEditorPane;

    /**
     * this method itfP used to draw the three levels of system:
     *  specification, configuration and assembly.
     * @param spec
     * @param config
     * @param container
     * @throws NoSuchInterfaceException 
     */
    public void drawArch(Specification spec, Configuration config, Component container) throws NoSuchInterfaceException {
        this.spec   = spec;
        this.config = config;
        this.ass    = container;

        // draw graphS: specification
        this.graphS = new JGraph();

        if (spec != null) {
            DrawSpecImpl ds = new DrawSpecImpl();

            ds.drawSpec((DefaultSpecification) spec);
            graphS = ds.graph;
            graphS.setName("graphS");
        }

        // draw graphC: configuration
        this.graphC = new JGraph();

        if (config != null) {
            DrawConfigImpl dc = new DrawConfigImpl();

            dc.drawConfig(config);
            graphC = dc.thisGraph;
            graphC.setName("graphC");
        }

        // draw graphA: assembly
        if (container != null) {
            this.graphA = new JGraph();

            DrawAssImpl da = new DrawAssImpl();
            da.drawAss(ass);
            graphA = da.getGraph();
            graphA.setName("graphA");
        }

        frame = new JFrame("Software Architectures");

        Menu menuBar = new Menu();

        frame.setJMenuBar(menuBar);

        // draw tree
       archTree = new ArchTree(spec, config, container);
        
        // ImageIcon icon = createImageIcon("images/middle.gif");
        archTreePanel = new JScrollPane(archTree);

        // set fileTreePane
        fileTreePanel = new JScrollPane(fileTree);

        // initiate viewTabbedPane
        viewTabbedPane = new JTabbedPane();

        // set viewTabbedPane with archTreePane and fileTreePane
        viewTabbedPane.addTab("Architecture Explorer", null, archTreePanel, "Architecture tree");
        viewTabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
        viewTabbedPane.addTab("File Navigator", null, fileTreePanel, "Project file tree");
        viewTabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
        viewTabbedPane.setSelectedIndex(0);

        // set xml file editor
        xmlEditorPane = new JEditorPane();
        xmlEditorPane.setEditable(false);

        // draw graph panel
 
////////////////
        graphPane = new JScrollPane(graphA);

      //set adlTextPane
        adlTextPane=new JTextPane();
        spec.setDocBNF(SpecADLText.createTextSpec(spec));
        config.setDocBNF(ConfigADLText.createTextConfig(config));
        Fractal.getAssemblyDescriptorController(ass).setDocBNF(AssADLText.createTextAss(ass));
        adlTextPane.setDocument(spec.getDocBNF());
        
        // create treetable for three arhcitectures
        if(spec!=null)
            specTreeTable = new JTreeTable(new ADLElementModel(spec));
        if(config!=null)
            configTreeTable = new JTreeTable(new ADLElementModel(config));
        if(ass!=null)
            assTreeTable = new JTreeTable(new ADLElementModel(ass));

        // draw table panel
        treeTablePane = new JScrollPane(assTreeTable);

        specTreeTable.setGridColor(Color.BLACK);
        
        propertyTabbedPane= new JTabbedPane();
     // setpropertyTabbedPane with archTreePane and fileTreePane
        propertyTabbedPane.addTab("BNF Expression", null, adlTextPane, "BNF ADL description of the architecture");
        propertyTabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
        propertyTabbedPane.addTab("Table Expression", null, treeTablePane, "Express architecture in table");
        propertyTabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
        propertyTabbedPane.setSelectedIndex(1);
        
        
        // initiate editorTabbedPane
        editorTabbedPane = new JTabbedPane();

        //
        //JSplitPane editorPane = new JSplitPane(graphPane);
        JScrollPane  editorPane=new JScrollPane(graphPane);
        
        
        // set editorTabbedPane with xmlEditorPane and  and fileTreePane
        editorTabbedPane.addTab("Graph Editor", null, editorPane, "Architecture graph");
        editorTabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
        editorTabbedPane.addTab("XML Editor", null, xmlEditorPane, "XML file");
        editorTabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
        editorTabbedPane.setSelectedIndex(0);


        // draw consolePane
        consoleTextArea = new JTextArea();
        consoleTextArea.setEditable(false);
        button = new JButton("clear");

        JToolBar consoleToolBar = new JToolBar();

        consoleToolBar.add(button);
        consolePane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, consoleToolBar, consoleTextArea);

        JSplitPane paneContent = new JSplitPane(JSplitPane.VERTICAL_SPLIT, editorTabbedPane, consolePane);

        paneContent.setDividerLocation(520);

        JSplitPane   paneLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, viewTabbedPane, paneContent);
        JSplitPane   paneMain = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, paneLeft, propertyTabbedPane);
        QuickToolBar toolBar  = new QuickToolBar();
        JSplitPane   pane     = new JSplitPane(JSplitPane.VERTICAL_SPLIT, toolBar, paneMain);

        // add console listener to frame and button
//        frame.addWindowListener(new ConsoleListener(frame, consoleTextArea));
//        button.addActionListener(new ConsoleListener(frame, consoleTextArea));

        // add listener to graphs
        SyncGraphSelectionListener syncGrpahSelectionListener = new SyncGraphSelectionListener(archTree, graphPane,
                                                                    graphS, graphC, graphA);

        if (spec != null) {
            graphS.addGraphSelectionListener(syncGrpahSelectionListener);
        }

        if (config != null) {
            graphC.addGraphSelectionListener(syncGrpahSelectionListener);
        }

        if (container != null) {
            graphA.addGraphSelectionListener(syncGrpahSelectionListener);
        }

        // add listener to archtree
        archTree.addTreeSelectionListener(new ArchTreeSelectionListener(archTree, editorTabbedPane, graphS, graphC,
                graphA, specTreeTable, configTreeTable, assTreeTable));

        // add listener to menu
        menuBar.addActionListener(fc, viewTabbedPane, editorTabbedPane, fileTree, fileTreePanel);
 //       menuBar.addActionListener(viewTabbedPane, spec, config, container);

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize  = new Dimension((int) (screenSize.width), (int) (screenSize.height));
        int       x          = (int) (0);
        int       y          = (int) (0);

        frame.setBounds(x, y, frameSize.width, frameSize.height - 50);
        paneLeft.setDividerLocation(280);
        paneMain.setDividerLocation(980);

        // paneContent.setDividerLocation(300);
        frame.getContentPane().add(pane);
        frame.setVisible(true);

        try {
            UIManager.setLookAndFeel("com.birosoft.liquid.LiquidLookAndFeel");
        } catch (ClassNotFoundException e1) {

            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (InstantiationException e1) {

            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {

            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (UnsupportedLookAndFeelException e1) {

            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        // JFrame.setDefaultLookAndFeelDecorated(true);
        // SwingUtilities.updateComponentTreeUI(frame);
        frame.setIconImage(new ImageIcon(Evolution.class.getResource("resource/icons/niu.png")).getImage());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // frame.dispose();
    }
}
